﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufBase.h"
#include "GnufItem.h"
#include "GnufSubject.h"
#include "GnufDropdownMenuControl.h"

namespace gnuf {
    class QtDropDownBoard;
    class Text;
    class AppearanceSetting;
    class DropDownBoardAppearanceSetting;

    class GNUF_BASE_EXPORT IDropDownBoardObserver
    {
    public:
        virtual void onBoardItemClicked(Item* item) {}
    };

    class GNUF_BASE_EXPORT DropDownBoard
        : public ItemWith<QtDropDownBoard>
        , public DropdownMenuControlAdpatation
        , public Subject<IDropDownBoardObserver>
    {
        GNUF_WATCHABLE_OBJECT(DropDownBoard)
        typedef DropdownMenuControlAdpatation::MenuItemType MenuItemType;
    public:
        static const EItemType Type;
        explicit DropDownBoard(Item*);
        explicit DropDownBoard(const gcmp::UniqueString * uniqueKey, Item*);
        virtual ~DropDownBoard();

    public:
        void addMenuItem(gcmp::OwnerPtr<Item>&&);
        bool insertMenuItem(int idx, gcmp::OwnerPtr<Item>&&);
        bool removeMenuItem(Item*);
        void removeAllMenuItem();
        // Separator不占用index
        void addSeparator();
        void setCurrentItem(Item*);
        int menuItemCount() const;
        int menuItemIndex(const Item*);
        virtual Item* menuItem(int idx) override;
        const Item* menuItem(int idx) const;
        bool isLastItemInGroup(Item*);
        std::vector<std::vector<gcmp::OwnerPtr<Item>>>& rawContents() { return m_menuItemGroups; }
        const std::vector<std::vector<gcmp::OwnerPtr<Item>>>& contents() const { return m_menuItemGroups; }

        void popup(int x, int y);

        inline void setIsInline(bool val) { m_isInline = val; }
        inline bool isInline() const { return m_isInline; }

        inline void setHasCheckStates(bool val) { m_hasCheckStates = val; }
        inline bool hasCheckStates() const { return m_hasCheckStates; }

        virtual void setCaption(const std::wstring&) override;
        std::wstring caption() const;

        inline bool hasCaption() const { return nullptr != m_caption.get(); }
        Text* captionItem() { return m_caption.get(); }

        int  getCurrentIndex() const { return m_currentIndex; }
        void setCurrentIndex(int index, bool withClick = true);

        bool closeOnClick() const { return m_closeOnClick; }
        void setCloseOnClick(bool is) { m_closeOnClick = is; }

        int displayNumPerPage() const { return m_displayNumPerPage; }
        void setDisplayNumPerPage(int);
        bool hasScrollBar() const { return m_displayNumPerPage != -1; }

        void setRecordDropDownUI(bool record) { m_recordMyUI = record; }
        bool recordDropDownUI() const { return m_recordMyUI; }

        const DropDownBoardAppearanceSetting* dropDownAppearanceSetting() const;
        DropDownBoardAppearanceSetting* customSetting();

        // 是否立即创建菜单项
        void enableDumpMenuItemImmediately(bool bEnabled) { m_isDumpMenuItemImmediately = bEnabled; }
        bool isDumpMenuItemImmediately() const { return m_isDumpMenuItemImmediately; }

    public:
        void onCurrentItemClick(Item*);
        void onClosed();

    protected:
        // Inherits from Item...
        virtual void onDisconnectFromMyQtItem() override;
        virtual void onPostAbilityChanged() override;
        virtual void onPostInfoChanged() override;
        virtual void onPostVisibilityChanged() override;
        virtual void onPostAppearanceSettingChanged() override;
        virtual void onChildVisibilityChanged(const Item*) override;

        // Inherits from DropdownMenuControlAdpatation...
        virtual void onVisibilityChanged(bool) override {}
        virtual void onAbilityChanged(bool) override {}
        virtual void onSelectionChanged(bool) override {}
        virtual void onCollectLocation(std::set<const gcmp::UniqueString *> &) const override;
        virtual void insertMenuItem(int, const Info&, MenuItemType) override;
        virtual void addMenuItem(const Info&, MenuItemType) override;
        virtual void addMenuGroup() override;
        virtual void removeMenuItem(int) override;
        virtual void renameMenuItem(int, const std::wstring&) override;
        virtual void renameMenuItemInfo(int, const Info&) override;
        virtual void selectMenuItem(int) override;
        virtual void setCustomizeArrowPathforIndexOfButton(int, const Info&) override;
        virtual void removeSeparator(int) override;
        virtual void menuItemCount(int& idx) const override { idx = menuItemCount(); }

    private:
        gcmp::OwnerPtr<Item> createMenuItem(const Info&, MenuItemType);
        DropDownBoard(const DropDownBoard&) = delete;
        DropDownBoard& operator=(const DropDownBoard&) = delete;

        static const AppearanceSetting& contextMenuAppearanceSetting();
    private:
        std::vector<std::vector<gcmp::OwnerPtr<Item>>> m_menuItemGroups;
        gcmp::OwnerPtr<Text> m_caption;
        bool m_hasCheckStates = false;
        bool m_isInline = false;
        int m_currentIndex = -1;
        bool m_closeOnClick = true;
        int m_displayNumPerPage = -1;
        bool m_recordMyUI = false;
        bool m_isDumpMenuItemImmediately = false;
        gcmp::OwnerPtr<DropDownBoardAppearanceSetting> m_customAppearanceSetting;
    };
}
